#    pythonequations is a collection of equations expressed as Python classes
#    Copyright (C) 2008 James R. Phillips
#    2548 Vera Cruz Drive
#    Birmingham, AL 35235 USA
#    email: zunzun@zunzun.com
#
#    License: BSD-style (see LICENSE.txt in main source directory)
#    Version info: $Id: Engineering.py 277 2010-10-20 16:56:49Z zunzun.com $

import pythonequations, pythonequations.EquationBaseClasses, pythonequations.ExtraCodeForEquationBaseClasses
import numpy
numpy.seterr(all = 'raise') # numpy raises warnings, convert to exceptions to trap them


class VanDeemter2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = False
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "VanDeemter Chromatography"
    _HTML = "y = a + b/x + cx"
    coefficientDesignatorTuple = ('a', 'b', 'c')
    CannotAcceptDataWithZeroX = True
    function_cpp_code = 'temp = coeff[0] + (coeff[1] * _id[_cwo[0]+i]) + (coeff[2] * _id[_cwo[1]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_PowX(NameOrValueFlag=1, args=[-1.0]), [-1.0]])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1, args=[4.0]), [4.0]])

    def SpecificCodeCPP(self):
        s = "\ttemp = a + b / x_in + c * x_in;\n"
        return s



class Dispersion2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = False
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Dispersion Optical"
    _HTML = "n<sup>2</sup>(x) = A1 + A2*x<sup>2</sup> + A3/x<sup>2</sup> + A4/x<sup>4</sup>"
    coefficientDesignatorTuple = ("A1", "A2", "A3", "A4")
    CannotAcceptDataWithZeroX = True
    function_cpp_code = 'temp = coeff[0] + (coeff[1] * _id[_cwo[0]+i]) + (coeff[2] / _id[_cwo[0]+i]) + (coeff[2] / _id[_cwo[1]+i]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_PowX(NameOrValueFlag=1, args=[2.0]), [2.0]])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_PowX(NameOrValueFlag=1, args=[4.0]), [4.0]])

    def SpecificCodeCPP(self):
        s = "\ttemp = A1 + (A2 * x_in * x_in) + (A3 / (x_in * x_in)) + (A4 / (x_in * x_in * x_in * x_in));\n"
        return s



class DispersionSqrt2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = False
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Dispersion Optical Square Root"
    _HTML = "n = (A1 + A2*x<sup>2</sup> + A3/x<sup>2</sup> + A4/x<sup>4</sup>)<sup>0.5</sup>"
    coefficientDesignatorTuple = ("A1", "A2", "A3", "A4")
    CannotAcceptDataWithZeroX = True
    function_cpp_code = 'temp = pow(coeff[0] + (coeff[1] * _id[_cwo[0]+i]) + (coeff[2] / _id[_cwo[0]+i]) + (coeff[2] / _id[_cwo[1]+i]), 0.5);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_PowX(NameOrValueFlag=1, args=[2.0]), [2.0]])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_PowX(NameOrValueFlag=1, args=[4.0]), [4.0]])

    def SpecificCodeCPP(self):
        s = "\ttemp = pow(A1 + (A2 * x_in * x_in) + (A3 / (x_in * x_in)) + (A4 / (x_in * x_in * x_in * x_in)), 0.5);\n"
        return s



class Sellmeier2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = False
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Sellmeier Optical"
    _HTML = "n<sup>2</sup>(x) = 1 + (B1 x<sup>2</sup>)/(x<sup>2</sup>-C1) +  (B2 x<sup>2</sup>)/(x<sup>2</sup>-C2) +  (B3 x<sup>2</sup>)/(x<sup>2</sup>-C3)"
    coefficientDesignatorTuple = ("B1", "C1", "B2", "C2", "B3", "C3")
    function_cpp_code = 'temp = 1.0 + ((coeff[0] * _id[_cwo[0]+i]) / (_id[_cwo[0]+i] - coeff[1])) + ((coeff[2] * _id[_cwo[0]+i]) / (_id[_cwo[0]+i] - coeff[3])) + ((coeff[4] * _id[_cwo[0]+i]) / (_id[_cwo[0]+i] - coeff[5]));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_PowX(NameOrValueFlag=1, args=[2.0]), [2.0]])

    def SpecificCodeCPP(self):
        s = "\ttemp = 1.0 + ((B1 * x_in * x_in)/(x_in * x_in - C1)) + ((B2 * x_in * x_in)/(x_in * x_in - C2)) + ((B3 * x_in * x_in)/(x_in * x_in - C3));\n"
        return s



class SellmeierSqrt2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = False
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Sellmeier Optical Square Root"
    _HTML = "n = (1 + (B1 x<sup>2</sup>)/(x<sup>2</sup>-C1) +  (B2 x<sup>2</sup>)/(x<sup>2</sup>-C2) +  (B3 x<sup>2</sup>)/(x<sup>2</sup>-C3))<sup>0.5</sup>"
    coefficientDesignatorTuple = ("B1", "C1", "B2", "C2", "B3", "C3")
    function_cpp_code = 'temp = 1.0 + ((coeff[0] * _id[_cwo[0]+i]) / (_id[_cwo[0]+i] - coeff[1])) + ((coeff[2] * _id[_cwo[0]+i]) / (_id[_cwo[0]+i] - coeff[3])) + ((coeff[4] * _id[_cwo[0]+i]) / (_id[_cwo[0]+i] - coeff[5]));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_PowX(NameOrValueFlag=1, args=[2.0]), [2.0]])

    def SpecificCodeCPP(self):
        s = "\ttemp = pow(1.0 + ((B1 * x_in * x_in)/(x_in * x_in - C1)) + ((B2 * x_in * x_in)/(x_in * x_in - C2)) + ((B3 * x_in * x_in)/(x_in * x_in - C3)), 0.5);\n"
        return s



class Ramberg_Osgood2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Ramberg-Osgood"
    _HTML = "y = (Stress / Young's Modulus) + (Stress&nbsp;/&nbsp;K)<SUP>(1.0&nbsp;/&nbsp;n)</SUP>"
    coefficientDesignatorTuple = ("Youngs_Modulus", "K", "n")
    function_cpp_code = 'temp = (_id[_cwo[0]+i] / coeff[0]) + pow(_id[_cwo[1]+i] / coeff[1], 1.0 / coeff[2]);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Ones(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Ones(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = ""
        j = self.coefficientDesignatorTuple # makes coding below easier to read

        s = "\ttemp = (x_in / " + j[0] + ") +  pow(x_in / " + j[1] + ", 1.0 / " + j[2] + ");\n"
        return s



class Steinhart_Hart2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = False
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Steinhart-Hart"
    _HTML = "1/T = A + Bln(R) + C(ln(R))<SUP>3</SUP>"
    coefficientDesignatorTuple = ("A", "B", "C")
    CannotAcceptDataWithZeroX = True
    CannotAcceptDataWithNegativeX = True
    function_cpp_code = 'temp = coeff[0] + (coeff[1] * _id[_cwo[0]+i]) + coeff[2] * pow(_id[_cwo[0]+i], 3.0);'
    guessDivisor = 50.0
    maxparamvalue = 1.0
    minparamvalue = -1.0


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_LogX(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = ""
        j = self.coefficientDesignatorTuple # makes coding below easier to read

        s = "\ttemp = " + j[0] + " + " + j[1] + "*log(x_in) + " + j[2] + "*pow(log(x_in), 3.0);\n"
        return s



class Reciprocal_Steinhart_Hart2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = False
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Reciprocal Steinhart-Hart"
    _HTML = "T = 1.0 / (A + Bln(R) + C(ln(R))<SUP>3</SUP>)"
    coefficientDesignatorTuple = ("A", "B", "C")
    CannotAcceptDataWithZeroX = True
    CannotAcceptDataWithNegativeX = True
    function_cpp_code = 'temp = 1.0 / (coeff[0] + (coeff[1] * _id[_cwo[0]+i]) + coeff[2] * pow(_id[_cwo[0]+i], 3.0));'
    guessDivisor = 50.0
    maxparamvalue = 1.0
    minparamvalue = -1.0


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_LogX(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = ""
        j = self.coefficientDesignatorTuple # makes coding below easier to read

        s = "\ttemp = 1.0 / (" + j[0] + " + " + j[1] + "*log(x_in) + " + j[2] + "*pow(log(x_in), 3.0));\n"
        return s



class Extended_Steinhart_Hart2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = False
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Extended Steinhart-Hart"
    _HTML = "1/T = A + Bln(R) + C(ln(R))<SUP>2</SUP> + D(ln(R))<SUP>3</SUP>"
    coefficientDesignatorTuple = ("A", "B", "C", "D")
    CannotAcceptDataWithZeroX = True
    CannotAcceptDataWithNegativeX = True
    function_cpp_code = 'temp = coeff[0] + (coeff[1] * _id[_cwo[0]+i]) + coeff[2] * pow(_id[_cwo[0]+i], 2.0) + coeff[3] * pow(_id[_cwo[0]+i], 3.0);'
    guessDivisor = 50.0
    maxparamvalue = 1.0
    minparamvalue = -1.0

    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_LogX(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = ""
        j = self.coefficientDesignatorTuple # makes coding below easier to read

        s = "\ttemp = " + j[0] + " + " + j[1] + "*log(x_in) + " + j[2] + "*pow(log(x_in), 2.0) + "+  j[3]  + "*pow(log(x_in), 3.0);\n"
        return s



class Reciprocal_Extended_Steinhart_Hart2D(pythonequations.EquationBaseClasses.Equation2D):
    RequiresAutoGeneratedGrowthAndDecayForms = False
    RequiresAutoGeneratedOffsetForm = False
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name = "Reciprocal Extended Steinhart-Hart"
    _HTML = "T = 1.0 / (A + Bln(R) + C(ln(R))<SUP>2</SUP> + D(ln(R))<SUP>3</SUP>)"
    coefficientDesignatorTuple = ("A", "B", "C", "D")
    CannotAcceptDataWithZeroX = True
    CannotAcceptDataWithNegativeX = True
    function_cpp_code = 'temp = 1.0 / (coeff[0] + (coeff[1] * _id[_cwo[0]+i]) + coeff[2] * pow(_id[_cwo[0]+i], 2.0) + coeff[3] * pow(_id[_cwo[0]+i], 3.0));'
    guessDivisor = 50.0
    maxparamvalue = 1.0
    minparamvalue = -1.0


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_LogX(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = ""
        j = self.coefficientDesignatorTuple # makes coding below easier to read

        s = "\ttemp = 1.0 / (" + j[0] + " + " + j[1] + "*log(x_in) + " + j[2] + "*pow(log(x_in), 2.0) + "+  j[3]  + "*pow(log(x_in), 3.0));\n"
        return s
